#include "ClientFunc.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>

struct PacketFile
{
    FILE *f;
    long FileSize;
    long currentPosition;
};

struct FileSystem
{
    char *dirPath;
};

MSG SignUp(char *MyName)
{
    MSG m;
    m.flag = SIGNUP; // 注册用户名
    printf("===================注册新用户====================\n");
    printf("请输入你的用户名:");
    scanf("%s", m.FromName);
    printf("请输入你的密码:");
    scanf("%s", m.Content);
    printf("================================================\n");
    strcpy(MyName, m.FromName);
    return m;
}

bool IsSignUpSuccess(MSG *m)
{
    if (strcmp(m->Content, "注册成功") == 0)
    {
        printf("注册成功！欢迎来到聊天室\n");
        return true;
    }
    else
    {
        printf("注册错误:%s\n", m->Content);
        return false;
    }
}
MSG Login(char *MyName)
{
    MSG m;
    m.flag = LOGIN; // 登录用户名
    printf("===================登录=========================\n");
    printf("请输入你的用户名:");
    scanf("%s", m.FromName);
    printf("请输入你的密码:");
    scanf("%s", m.Content);
    printf("================================================\n");
    strcpy(MyName, m.FromName);
    return m;
}

bool IsLoginSuccess(MSG *m)
{
    if (strcmp(m->Content, "登录成功") == 0)
    {
        printf("登录成功！欢迎来到聊天室\n");
        return true;
    }
    else
    {
        printf("登录错误:%s\n", m->Content);
        return false;
    }
}

/* 私聊 */
MSG ChatToClient()
{
    MSG m;
    memset(&m, 0, sizeof(m));
    m.flag = CHAT;
    char msg[100] = {0};
    printf("请输入你要发送的用户名称：");
    scanf("%s", m.ToName);
    printf("请输入你要发送给的消息：");
    scanf("%s", m.Content);
    return m;
}

/* 功能选择界面 */
int Interface()
{
    printf("===================欢迎来到聊天室====================\n");
    printf("1、私聊\n");
    // printf("2、广播\n");
    printf("2、查看在线用户\n");
    printf("3、文件发送\n");
    printf("4、我的网盘\n");
    printf("5、好友管理\n");
    printf("6、群聊管理\n");
    printf("====================================================\n");
    printf("请选择你要的功能:");
    int choice = 0;
    scanf("%d", &choice);
    return choice;
}

int LoginFace()
{
    system("clear");
    printf("===================聊天室登录========================\n");
    printf("1、注册\n");
    printf("2、登录\n");
    printf("====================================================\n");
    printf("请选择你要的功能:");
    int choice = 0;
    scanf("%d", &choice);
    return choice * (-1);
}

// MSG ChatBroadCast()
// {
//     MSG m;
//     m.flag = BROADCAST;
//     printf("请输入你要发送的信息:");
//     scanf("%s", m.Content);
//     return m;
// }

MSG GetServerOnlineList()
{
    MSG m;
    m.flag = ONLINELIST;
    return m;
}

void ShowOnlineList(MSG *m)
{
    char str[ContentSize] = {0};
    strcpy(str, m->Content);
    char *dest = strtok(str, ",");
    int count = 1;
    while (dest != NULL)
    {
        printf("%d:%s\n", count++, dest);
        dest = strtok(NULL, ",");
    }
}

MSG SendFile()
{
    MSG m;
    m.flag = SENDFILE;
    printf("请输入你要发送的文件路径:");
    scanf("%s", m.Content);
    printf("请输入你要发送的用户:");
    scanf("%s", m.ToName);
    return m;
}

char *GetFileNameFromPath(const char *filePath)
{
    char str[ContentSize] = {0};
    strcpy(str, filePath);

    char *dest = strtok(str, "/");
    char *fileName = NULL;
    while (dest != NULL)
    {
        fileName = dest;
        dest = strtok(NULL, "/");
    }
    char *result = strdup(fileName); // filename为局部变量的指针，要重新存储在堆内存
    return result;
}

void WriteToLocal(MSG *m)
{
    int size = 0;
    memcpy(&size, m->Content, sizeof(int));

    char fileName[NameSize] = {0};
    strcpy(fileName, m->Content + 4);
    char filePath[ContentSize] = {0};
    sprintf(filePath, "./%s", fileName);
    if (size == -1)
    {
        printf("文件%s传输完成\n", fileName);
    }
    FILE *f = fopen(filePath, "a");
    fwrite(m->Content + 24, size, 1, f);
    fclose(f);
}

MSG UpLoadFile()
{
    MSG m;
    m.flag = UPLOAD;
    printf("请输入要上传的文件路径:");
    scanf("%s", m.Content);
    return m;
}

MSG DownloadFile()
{
    MSG m;
    m.flag = DOWNLOAD;
    printf("请输入要下载的文件名称:");
    scanf("%s", m.Content);
    return m;
}

/* 自定义字符串切割函数 */
char **Split(const char *str, const char *delim, int *size) // 参数：目标字符串， 切割标识符， 切割的字符串个数
{
    char *SplitStr = strdup(str);

    char **result = (char **)malloc(sizeof(char *) * 50);
    if (result == NULL)
    {
        printf("Split malloc error\n");
        return NULL;
    }

    int count = 0;
    char *dest = strtok(SplitStr, delim);
    while (dest != NULL)
    {
        result[count++] = strdup(dest);
        dest = strtok(NULL, delim);
    }
    free(SplitStr);
    *size = count;
    return result;
}

// 释放二维数组
void FreeStrList(char **strList, int size)
{
    for (int i = 0; i < size; i++)
    {
        free(strList[i]);
    }
    free(strList);
}

void ShowFIleList(MSG *m)
{
    if (strcmp(m->Content, "FILEERROR") == 0)
    {
        printf("获取网盘文件失败\n");
        return;
    }
    int fileCount = 0;
    char **file = Split(m->Content, ",", &fileCount);
    for (int i = 0; i < fileCount; i++)
    {
        int count = 0;
        char **fileInfo = Split(file[i], ";", &count);
        if (count != 2)
        {
            FreeStrList(fileInfo, count);
            continue;
        }
        printf("%d : 文件名：|%s|  文件大小：|%s|\n", i + 1, fileInfo[0], fileInfo[1]);
        FreeStrList(fileInfo, count);
    }
    FreeStrList(file, fileCount);
}

int CloudInterface()
{
    printf("=====================我的网盘=========================\n");
    printf("1、查看网盘文件\n");
    printf("2、上传文件\n");
    printf("3、下载文件\n");
    printf("4、退回到主界面\n");
    printf("======================================================\n");
    printf("请输入你的选择:");
    int choice = 0;
    scanf("%d", &choice);
    return FILELIST + choice - 1;
}

int FriendFace()
{
    printf("====================好友管理界面========================\n");
    printf("1、添加好友\n");
    printf("2、删除好友\n");
    printf("3、查看好友列表\n");
    printf("4、查看好友请求\n");
    printf("5、好友请求处理\n");
    printf("6、退回到主界面\n");
    printf("======================================================\n");
    printf("请输入你的选择:");
    int choice = 0;
    scanf("%d", &choice);
    return ADDFRIEND + choice - 1;
}

MSG AddFriend()
{
    MSG m;
    memset(&m, 0, sizeof(m));
    m.flag = ADDFRIEND;
    printf("请输入你要加的好友的用户名：");
    scanf("%s", m.ToName);
    return m;
}

MSG IsFriendOk()
{
    MSG m;
    m.flag = ISFREIEND;
    printf("请输入申请者姓名:");
    scanf("%s", m.ToName);
    printf("====================来自|%s|的好友请求========================\n", m.ToName);
    printf("1、同意\n");
    printf("2、拒绝\n");
    printf("======================================================\n");
    printf("请输入你的选择:");
    scanf("%s", m.Content);
    return m;
}

MSG DelFriend()
{
    MSG m;
    memset(&m, 0, sizeof(m));
    m.flag = DELFRIEND;
    printf("请输入你要删除的好友的用户名：");
    scanf("%s", m.ToName);
    return m;
}

// 左边打印
void left(const char *content)
{
    printf("%s\n", content);
}

// 右边打印
void right(const char *content)
{
    printf("                                     %s\n", content);
}

// 消息显示
void MessageShow(const char *content, int flag)
{
    if (flag == 0)
    {
        right(content);
    }
    else if (flag == 1)
    {
        left(content);
    }
}

void PrivateChatFace(MSG *m, const char *MyName)
{
    if (strcmp(m->FromName, MyName) == 0)
    {
        printf("==========================|%s|(1退出)=======================\n", m->ToName);
    }
    else
    {
        printf("==========================|%s|(1退出)=======================\n", m->FromName);
    }
}

int GroupManageFace()
{
    printf("====================群聊管理界面========================\n");
    printf("1、创建群聊\n");
    printf("2、删除群聊\n");
    printf("3、加入群聊\n");
    printf("4、退出群聊\n");
    printf("5、群聊\n");
    printf("6、退回到主界面\n");
    printf("======================================================\n");
    printf("请输入你的选择:");
    int choice = 0;
    scanf("%d", &choice);
    return GREATEGROUP + choice - 1;
}

MSG GreateGroup()
{
    MSG m;
    memset(&m, 0, sizeof(m));
    m.flag = GREATEGROUP;
    printf("请输入创建的群聊名称：");
    scanf("%s", m.ToName);
    return m;
}

MSG DeleteGroup()
{
    MSG m;
    memset(&m, 0, sizeof(m));
    m.flag = DELETEGROUP;
    printf("请输入删除的群聊名称：");
    scanf("%s", m.ToName);
    return m;
}

MSG JoinGroup()
{
    MSG m;
    memset(&m, 0, sizeof(m));
    m.flag = JOINGROUP;
    printf("请输入加入的群聊名称：");
    scanf("%s", m.ToName);
    return m;
}

MSG LeaveGroup()
{
    MSG m;
    memset(&m, 0, sizeof(m));
    m.flag = LEAVEGROUP;
    printf("请输入退出的群聊名称：");
    scanf("%s", m.ToName);
    return m;
    return m;
}

MSG ChatGroup()
{
    MSG m;
    memset(&m, 0, sizeof(m));
    m.flag = CHATGROUP;
    printf("请输入你要发送的群聊名称：");
    scanf("%s", m.ToName);
    printf("请输入你要发送给的消息：");
    scanf("%s", m.Content);
    return m;
}

void GroupChatFace(MSG *m)
{
    printf("==========================|%s|(1退出)=======================\n", m->ToName);
}

PackFile *PacketFileInit(const char *filePath)
{
    PackFile *pf = (PackFile *)malloc(sizeof(PackFile));
    if (pf == NULL)
    {
        printf("PacketFileInit malloc error\n");
        return NULL;
    }

    pf->f = fopen(filePath, "r"); // 以最小权限发送
    if (pf->f == NULL)
    {
        printf("打开|%s|文件失败\n", filePath);
        free(pf);
        return NULL;
    }

    fseek(pf->f, 0, SEEK_END);
    pf->FileSize = ftell(pf->f);
    fseek(pf->f, 0, SEEK_SET);

    pf->currentPosition = 0;
    printf("文件大小：%ld,文件位置：%ld\n", pf->FileSize, pf->currentPosition);

    return pf;
}

void ReadFromFile(PackFile *f, void *p, int *size)
{
    if (*size + f->currentPosition > f->FileSize)
    {
        *size = f->FileSize - f->currentPosition;
    }
    fread(p, *size, 1, f->f);
    f->currentPosition += *size;
}

bool IsFileEnd(PackFile *f)
{
    return f->currentPosition == f->FileSize;
}

void ClearPacketFile(PackFile *f)
{
    fclose(f->f);
    free(f);
}

// FileSys *FileSystemInit(const char *DirPath)
// {
//     FileSys *fs = (FileSys *)malloc(sizeof(DirPath));
//     if (fs == NULL)
//     {
//         printf("FileSystemInit malloc error!\n");
//     }

//     DIR *dir;
//     if ((dir = opendir(DirPath)) == NULL)
//     {
//         if (mkdir(DirPath, 0777) != 0)
//         {
//             perror("mkdir");
//             free(fs);
//             return NULL;
//         }
//         fs->dirPath = strdup(DirPath);
//         return fs;
//     }
//     else
//     {
//         closedir(dir);
//         fs->dirPath = strdup(DirPath);
//         return fs;
//     }
// }

// bool CreateNewDirInFs(FileSys *fs, const char *DirName)
// {
//     char DirPath[1024] = {0};
//     sprintf(DirPath, "%s/%s", fs->dirPath, DirName);
//     if (mkdir(DirPath, 0777) != 0)
//     {
//         perror("mkdir");
//         return false;
//     }
//     return true;
// }

// void WriteFileToFs(FileSys *fs, const char *DirName, const char *fileName, void *p, size_t size)
// {
//     char filePath[1024] = {0};
//     sprintf(filePath, "%s/%s/%s", fs->dirPath, DirName, fileName);
//     FILE *f = fopen(filePath, "a");
//     fwrite(p, size, 1, f);
//     fclose(f);
// }